/**
 * Created by seth.yang on 2016/9/20
 */
(function ($) {
    if ($.fn.asComboBox) {
        return;
    }

    var holder = {
        index : -1,
        max   : 0
    };

    function show (panel) {
        panel.show ();
        panel.isShow = true;
    }

    function hide (panel) {
        panel.empty ().hide ();
        panel.isShow = false;
        //holder.max   = 0;
        holder.index = -1;
    }

    function onEnter (settings) {
        if (holder.index < 0) {
            holder.index = 0;
        }
        if (holder.index >= 0) {
            var item = $(panel.find ('li')[holder.index]).find ('a');
            if (item) {
                var id = item.attr ('data-id'), text = item.text ();
                fireOnSelected (id, text, settings);
            }
            hide (panel);
        }
    }

    function fireOnSelected (id, text, settings) {
        if (settings && ('onselect' in settings)) {
            settings ['onselect'] (id, text);
        }
    }

    function onMoveUp () {
        if (!panel.isShow) return;
        var lastIndex = holder.index;
        if (holder.index > 0) {
            holder.index --;
        } else {
            holder.index = holder.max - 1;
        }
        highlight (lastIndex, holder.index);
    }

    function onMoveDown () {
        if (!panel.isShow) return;
        var lastIndex = holder.index;
        if (holder.index < holder.max - 1) {
            holder.index ++;
        } else {
            holder.index = 0;
        }
        highlight (lastIndex, holder.index);
    }

    function highlight (last, now) {
        var items = panel.find ('li');
        var item = $(items [last]);
        item.removeClass ('cb-item-current');
        item = $(items [now]);
        item.addClass ('cb-item-current');
    }

    var panel = $ ('<ul class="cb-root"/>'), fillPanel = function (keyword, data, options) {
        hide (panel);
        var idField = options ['id'], textField = options ['text'];
            //keywordField = options ['keyword'],
            //keyword = tip[keywordField];
        for (var i = 0; i < data.length; i ++) {
            var li = $('<li/>').appendTo (panel);
            var a  = $('<a class="cb-item"/>').attr ('data-id', data [i][idField]).appendTo (li);
            var text = data[i][textField];
            if (text) {
                var pos = text.indexOf (keyword);
                if (pos >= 0) {
                    var last = text.substring(pos + keyword.length);
                    var span = $('<span class="cb-keyword"/>').text(keyword);
                    a.text(text.substring(0, pos));
                    span.appendTo(a);
                    a.html(a.html() + last);
                } else {
                    a.text (text);
                }
                a.on ('click', function () {
                    var self = $(this), id = self.attr ('data-id'), text = self.text ();
                    fireOnSelected (id, text, options);
                    hide (panel);
                });
            }
        }
    }, fetchData = function (sender, parameters, options) {
        ('onbeforequery' in options) &&
            (options ['onbeforequery']) (parameters || {});
        $.ajax ({
            url:options['url'],
            data:parameters,
            type:options['method']
        }).success (function (response) {
            var ret = eval ('(' + response + ')');
            var keyword_name = options ['keyword'];
            if (ret && ret ['status'] == 'ok') {
                var data = ret ['data'];
                if (data && data.length) {
                    holder.max   = data.length;
                    holder.index = -1;
                    fillPanel(parameters [keyword_name], data, options);
                    var position = sender.offset();
                    var w = sender.width (), h = sender.height ();
                    var pt = parseInt (sender.css ('paddingTop')),
                        pb = parseInt (sender.css ('paddingBottom')),
                        pl = parseInt (sender.css ('paddingLeft')),
                        pr = parseInt (sender.css ('paddingRight'));
                    if (pt) h += pt;
                    if (pb) h += pb;
                    if (pl) w += pl;
                    if (pr) w += pr;

                    show (panel.css({
                        left: position.left,
                        top: position.top + h,
                        width: w
                    }));
                } else {
                    hide (panel);
                }
            } else {
                alert ('fetch data fail');
            }
        }).error (function (e, response) {alert (e + ", \r\n" + response);});
    };

    $(function () {
        panel.appendTo ($(document.body));
    });

    $.fn.asComboBox = function (options) {
        return this.each (function () {
            var self = $(this).attr ('autocomplete', 'off').addClass ('cb-input');
            //self.data ('settings', options);
            self.unbind ('keyup').unbind ('focus').on ('keyup', function (e) {
                switch (e.keyCode) {
                    case 13: { // enter
                        if (panel.isShow) {
                            onEnter (options);
                        }
                        break;
                    }
                    case 27: // escape
                        hide (panel);
                        self.val ('');
                        break;
                    case 37: // left
                        break;
                    case 38: // up
                        onMoveUp ();
                        break;
                    case 39: // right
                        break;
                    case 40: // down
                        onMoveDown ();
                        break;
                    default: {
                        var keyword = this.value;
                        if (keyword) {
                            var parameters = options ['parameters'];
                            parameters = $.extend({}, parameters || {});
                            parameters[options ['keyword']] = keyword;

                            fetchData($(this), parameters, options);
                        } else {
                            panel.empty ().hide ();
                            panel.isShow = false;
                            ('onclear' in options) && (options ['onclear']) ();
                        }
                        break;
                    }
                }
            }).on ('focus', function () {
                panel.target = $(this);
            });
        });
    };
})(jQuery);